using System;
using System.Collections.Generic;
using System.Text;
using Csla.Data;
using Csla;
using Active.Core.DB;
using Csla.Validation;

namespace Active.Core
{
    [Serializable()]
    public class MediaOrder : BusinessBase<MediaOrder>
    {
        #region Business Methods

        // TODO: add your own fields, properties and methods
        private int _id;

        public int Id
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _id;
            }
        }

        string _description;
        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>The description.</value>
        public string Description
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _description;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (_description!=value)
                {
                    _description = value;
                    PropertyHasChanged();
                }
            }
        }

        double _discount;
        /// <summary>
        /// Gets or sets the discount.
        /// </summary>
        /// <value>The discount.</value>
        public double Discount
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _discount;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (!_discount.Equals(value))
                {
                    _discount = value;
                    PropertyHasChanged();
                }
            }
        }

        string _duration;
        /// <summary>
        /// Gets or sets the duration.
        /// </summary>
        /// <value>The duration.</value>
        public string Duration
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _duration;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (_duration!=value)
                {
                    _duration = value;
                    PropertyHasChanged();
                }
            }
        }

        string _mediaEmployee;
        /// <summary>
        /// Gets or sets the media employee.
        /// </summary>
        /// <value>The media employee.</value>
        public string MediaEmployee
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _mediaEmployee;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (_mediaEmployee!=value)
                {
                    _mediaEmployee = value;
                    PropertyHasChanged();
                }
            }
        }

        int _orderId;
        /// <summary>
        /// Gets or sets the order id.
        /// </summary>
        /// <value>The order id.</value>
        public int OrderId
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _orderId;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (!_orderId.Equals(value))
                {
                    _orderId = value;
                    PropertyHasChanged();
                }
            }
        }

        int _customerOrderId;
        /// <summary>
        /// Gets or sets the customer order id.
        /// </summary>
        /// <value>The customer order id.</value>
        public int CustomerOrderId
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _customerOrderId;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (!_customerOrderId.Equals(value))
                {
                    _customerOrderId = value;
                    PropertyHasChanged();
                }
            }
        }

        string _position;
        /// <summary>
        /// Gets or sets the position.
        /// </summary>
        /// <value>The position.</value>
        public string Position
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _position;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (_position!=value)
                {
                    _position = value;
                    PropertyHasChanged();
                }
            }
        }

        decimal _payout;
        /// <summary>
        /// Gets or sets the payout.
        /// </summary>
        /// <value>The payout.</value>
        public decimal Payout
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _payout;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (!_payout.Equals(value))
                {
                    _payout = value;
                    PropertyHasChanged();
                }
            }
        }

        int _times;
        /// <summary>
        /// Gets or sets the times.
        /// </summary>
        /// <value>The times.</value>
        public int Times
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _times;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (!_times.Equals(value))
                {
                    _times = value;
                    PropertyHasChanged();
                }
            }
        }

        string _timeSlot;
        /// <summary>
        /// Gets or sets the time slot.
        /// </summary>
        /// <value>The time slot.</value>
        public string TimeSlot
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _timeSlot;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (_timeSlot!=value)
                {
                    _timeSlot = value;
                    PropertyHasChanged();
                }
            }
        }

        decimal _unitPrice;
        /// <summary>
        /// Gets or sets the unit price.
        /// </summary>
        /// <value>The unit price.</value>
        public decimal UnitPrice
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _unitPrice;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (!_unitPrice.Equals(value))
                {
                    _unitPrice = value;
                    PropertyHasChanged();
                }
            }
        }

        string _channel;
        /// <summary>
        /// Gets or sets the channel.
        /// </summary>
        /// <value>The channel.</value>
        public string Channel
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _channel;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (_channel != value)
                {
                    _channel = value;
                    PropertyHasChanged();
                }
            }
        }

        string _campaignPeriod;
        /// <summary>
        /// Gets or sets the campaign period.
        /// </summary>
        /// <value>The campaign period.</value>
        public string CampaignPeriod
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _campaignPeriod;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (_campaignPeriod != value)
                {
                    _campaignPeriod = value;
                    PropertyHasChanged();
                }
            }
        }

        OrderType _category = OrderType.Pay;
        /// <summary>
        /// Gets or sets the category.
        /// </summary>
        /// <value>The category.</value>
        public OrderType Category
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return _category;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (!_category.Equals(value))
                {
                    _category = value;
                    PropertyHasChanged();
                }
            }
        }
        
        protected override object GetIdValue()
        {
            return _id;
        }

        #endregion

        #region Validation Rules

        protected override void AddBusinessRules()
        {
            // TODO: add validation rules
            ValidationRules.AddRule(CommonRules.MinValue<int>,
                new Csla.Validation.CommonRules.MinValueRuleArgs<int>("CustomerOrderId", 1));
        }

        #endregion

        #region Authorization Rules

        protected override void AddAuthorizationRules()
        {
            // TODO: add authorization rules
            //AuthorizationRules.AllowWrite("", "");
        }

        /// <summary>
        /// Determines whether this instance [can add object].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if this instance [can add object]; otherwise, <c>false</c>.
        /// </returns>
        public static bool CanAddObject()
        {
            return Utils.IsMediaEmployee || Utils.IsMediaManager;
        }

        /// <summary>
        /// Determines whether this instance [can get object].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if this instance [can get object]; otherwise, <c>false</c>.
        /// </returns>
        public static bool CanGetObject()
        {
            return Utils.IsMediaEmployee || Utils.IsMediaManager 
                || Utils.IsGeneralManager
                || Utils.IsFinanceEmployee;
        }

        /// <summary>
        /// Determines whether this instance [can edit object].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if this instance [can edit object]; otherwise, <c>false</c>.
        /// </returns>
        public static bool CanEditObject()
        {
            return Utils.IsMediaEmployee || Utils.IsMediaManager;
        }

        /// <summary>
        /// Determines whether this instance [can delete object].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if this instance [can delete object]; otherwise, <c>false</c>.
        /// </returns>
        public static bool CanDeleteObject()
        {
            return Utils.IsMediaEmployee || Utils.IsMediaManager;
        }

        #endregion

        #region Factory Methods

        internal static MediaOrder NewMediaOrder()
        {
            // TODO: change to use new keyword if not loading defaults
            return new MediaOrder();
            //return DataPortal.Create<CustomerOrder>();
        }

        internal static MediaOrder GetMediaOrder(SafeDataReader dr)
        {
            return new MediaOrder(dr);
        }

        private MediaOrder()
        {
            MarkAsChild();
        }

        private MediaOrder(SafeDataReader dr)
        {
            MarkAsChild();
            Fetch(dr);
        }

        #endregion

        #region Data Access

        private void Fetch(SafeDataReader dr)
        {
            _id = dr.GetInt32("Id");
            _campaignPeriod = dr.GetString("CampaignPeriod");
            _category = (OrderType)dr.GetInt32("Category");
            _channel = dr.GetString("Channel");
            _customerOrderId = dr.GetInt32("CustomerOrderId");
            _description = dr.GetString("Description");
            _discount = dr.GetDouble("Discount");
            _duration = dr.GetString("Duration");
            _mediaEmployee = dr.GetString("MediaEmployee");
            _orderId = dr.GetInt32("OrderId");
            _payout = dr.GetDecimal("Payout");
            _position = dr.GetString("Position");
            _times = dr.GetInt32("Times");
            _timeSlot = dr.GetString("TimeSlot");
            _unitPrice = dr.GetDecimal("UnitPrice");

            MarkOld();
        }

        internal void Insert(Order parent)
        {
            _orderId = parent.Id;
            _mediaEmployee = Csla.ApplicationContext.User.Identity.Name;

            NBearLite.InsertSqlSection insert =
                DataService.DBService.Insert(Tables.MediaOrders)
                .AddColumn(Tables.MediaOrders.CampaignPeriod, _campaignPeriod)
                .AddColumn(Tables.MediaOrders.Category, _category)
                .AddColumn(Tables.MediaOrders.Channel, _channel)
                .AddColumn(Tables.MediaOrders.CustomerOrderId, _customerOrderId)
                .AddColumn(Tables.MediaOrders.Description, _description)
                .AddColumn(Tables.MediaOrders.Discount, _discount)
                .AddColumn(Tables.MediaOrders.Duration, _duration)
                .AddColumn(Tables.MediaOrders.MediaEmployee, _mediaEmployee)
                .AddColumn(Tables.MediaOrders.OrderId, _orderId)
                .AddColumn(Tables.MediaOrders.Payout, _payout)
                .AddColumn(Tables.MediaOrders.Position, _position)
                .AddColumn(Tables.MediaOrders.Times, _times)
                .AddColumn(Tables.MediaOrders.TimeSlot, _timeSlot)
                .AddColumn(Tables.MediaOrders.UnitPrice, _unitPrice);
            _id = insert.ExecuteReturnAutoIncrementID(Tables.MediaOrders.Id);
            MarkOld();
        }

        internal void Update(Order parent)
        {
            _orderId = parent.Id;
            ValidationRules.CheckRules();
            NBearLite.UpdateSqlSection update =
                DataService.DBService.Update(Tables.MediaOrders)
                .AddColumn(Tables.MediaOrders.CampaignPeriod, _campaignPeriod)
                .AddColumn(Tables.MediaOrders.Category, _category)
                .AddColumn(Tables.MediaOrders.Channel, _channel)
                .AddColumn(Tables.MediaOrders.CustomerOrderId, _customerOrderId)
                .AddColumn(Tables.MediaOrders.Description, _description)
                .AddColumn(Tables.MediaOrders.Discount, _discount)
                .AddColumn(Tables.MediaOrders.Duration, _duration)
                .AddColumn(Tables.MediaOrders.MediaEmployee, _mediaEmployee)
                .AddColumn(Tables.MediaOrders.OrderId, _orderId)
                .AddColumn(Tables.MediaOrders.Payout, _payout)
                .AddColumn(Tables.MediaOrders.Position, _position)
                .AddColumn(Tables.MediaOrders.Times, _times)
                .AddColumn(Tables.MediaOrders.TimeSlot, _timeSlot)
                .AddColumn(Tables.MediaOrders.UnitPrice, _unitPrice)
                .Where(Tables.MediaOrders.Id == _id);
            update.Execute();
            MarkOld();
        }

        internal void DeleteSelf()
        {
            DataService.DBService.Delete(Tables.MediaOrders)
                .Where(Tables.MediaOrders.Id == _id).Execute();
            MarkNew();
        }

        #endregion
    }
}
